home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Archive-tools / untar and compress Folder / untar / untar.c < prev    next >
C/C++ Source or Header  |  1993-03-12  |  8KB  |  358 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <console.h>
  4. #include    <unix.h>
  5. #include    <StandardFile.h>
  6. #include    <Files.h>
  7. #include    <Dialogs.h>
  8.  
  9. typedef unsigned char    uchar;
  10. typedef unsigned short    ushort;
  11. typedef unsigned long    ulong;
  12.  
  13. #define    NAMESIZE    100
  14.  
  15. typedef struct
  16. {
  17.     char    name[NAMESIZE];
  18.     char    mode[8];
  19.     char    uid[8];
  20.     char    gid[8];
  21.     char    size[12];
  22.     char    mtime[12];
  23.     char    checksum[8];
  24.     char    link[NAMESIZE+2];
  25.     char    extno[4];
  26.     char    exttotal[4];
  27.     char    efsize[12];
  28. } FileInfo;
  29.  
  30. #define    DIGIT(x)    ('0' <= (x) && (x) <= '7')
  31. #define    VALUE(x)    ((x) - '0')
  32.  
  33. char    block[ 512 ];
  34.  
  35. int        listflag = 1;
  36.  
  37. ulong    readnum( char * dp, int maxsize );
  38. void    main( int argc, char ** argv );
  39. void    HiliteDefault( DialogPtr d );
  40.  
  41. ulong    readnum( char * dp, int maxsize )
  42. {
  43.     ulong    answer = 0;
  44.     
  45.     while ( ! DIGIT(*dp) && --maxsize > 0 )
  46.         dp++;
  47.     while ( DIGIT(*dp) && maxsize-- > 0 )
  48.         answer = answer * 8 + VALUE(*dp++);
  49.     return answer;
  50. }
  51.  
  52. void    main( int argc, char ** argv )
  53. {
  54.     int            i, j;
  55.     long        size;
  56.     int            dflag;
  57.     FileInfo    * fp;
  58.     char        * ep;
  59.     HParamBlockRec    h;
  60.     Handle        kirk;
  61.     extern long _fcreator;
  62.     Point        p;
  63.     SFReply        reply;
  64.     OSErr        err;
  65.     FILE        * in;
  66.     DialogPtr    dp;
  67.     char        tempstr[33];
  68.     long        templ;
  69.     int            itemType, itemHit;
  70.     Handle        item;
  71.     Rect        itemRect;
  72.     int            forceFlag = 0;
  73.     int            convertFlag = 0;
  74.     
  75.     kirk = GetResource( 'KIRK', 128 );
  76.     _fcreator = **(long **)kirk;
  77.     
  78.  
  79.     printf("\n\n" );
  80.     printf( "Simple tar extraction utility, version 1.0, by Tim Smith.\n" );
  81.     printf( "This program and its source code are in the public domain.\n" );
  82.     printf( "\n" );
  83.     printf( "Follow the instructions that will be displayed at the bottom\n" );
  84.     printf( "of this window for each dialog that is displayed.\n" );
  85.     
  86.     dp = GetNewDialog( 128, 0, (WindowPtr)-1 );
  87.     
  88. StartOver:
  89.     printf( "\n========================================\n" );
  90.     printf( "Select a tar archive.\n" );
  91.     fflush( stdout );
  92.     p.h = 200;
  93.     p.v = 50;
  94.     SFGetFile( p, 0, 0, -1, 0, 0, &reply );
  95.     
  96.     if ( reply.good == TRUE )
  97.     {
  98.         PtoCstr( reply.fName );
  99.         err = SetVol( 0, reply.vRefNum );
  100.         if ( err )
  101.         {
  102.             printf( "ERROR: could not set directory!\n" );
  103.             fflush( stdout );
  104.             goto StartOver;
  105.         }
  106.         in = fopen( (char *)reply.fName, "rb" );
  107.         if ( in == NULL )
  108.         {
  109.             printf( "ERROR: could not open file!\n" );
  110.             fflush( stdout );
  111.             goto StartOver;
  112.         }
  113.     }
  114.     else
  115.         ExitToShell();
  116.         
  117.     fp = (FileInfo *)block;
  118.  
  119. RedoDialog:
  120.     printf( "\n========================================\n" );
  121.     printf( "Archive is %s.\n", reply.fName );
  122.     printf( "\n" );
  123.     printf( "Press LIST to get a listing of the files in the archive.  They will be\n" );
  124.     printf( "listed with their Unix name (e.g., '/' between components of a path).\n" );
  125.     printf( "\n" );
  126.     printf( "Press EXTRACT to extract all of the files in the archive.  Directories\n" );
  127.     printf( "will be created as needed.\n" );
  128.     printf( "\n" );
  129.     printf( "Press CANCEL to return to the file selection dialog.\n" );
  130.     printf( "\n" );
  131.     printf( "Set the creator to use for extracted files in the text edit box, and\n" );
  132.     printf( "control conversion of text files from Unix to Mac format with the check\n" );
  133.     printf( "box. The default creator is in the KIRK 128 resource, by the way.\n" );
  134.     fflush( stdout );
  135.     GetDItem( dp, 4, &itemType, &item, &itemRect );
  136.     tempstr[0] = 4;
  137.     tempstr[1] = _fcreator >> 24;
  138.     tempstr[2] = _fcreator >> 16;
  139.     tempstr[3] = _fcreator >> 8;
  140.     tempstr[4] = _fcreator;
  141.     SetIText( item, tempstr );
  142.     
  143.     GetDItem( dp, 5, &itemType, &item, &itemRect );
  144.     SetCtlValue( item, 1 );
  145.     
  146.     ShowWindow( dp );
  147.     SelectWindow( dp );
  148.     SelIText( dp, 4, 0, -1 );
  149.     
  150.     do
  151.     {
  152.         HiliteDefault( dp );
  153.         ModalDialog( 0, &itemHit );
  154.         if ( itemHit == 5 )
  155.         {
  156.             GetDItem( dp, 5, &itemType, &item, &itemRect );
  157.             SetCtlValue( item, 1 - GetCtlValue(item) );
  158.         }
  159.     }
  160.     while ( itemHit != 1 && itemHit != 2 && itemHit != 3 );
  161.     
  162.     GetDItem( dp, 5, &itemType, &item, &itemRect );
  163.     convertFlag = GetCtlValue(item);
  164.  
  165.     HideWindow( dp );
  166.     
  167.     if ( itemHit == 3 )
  168.     {
  169.         fclose( in );
  170.         goto StartOver;
  171.     }
  172.     
  173.     GetDItem( dp, 4, &itemType, &item, &itemRect );
  174.     GetIText( item, tempstr );
  175.     if ( tempstr[0] != 4 )
  176.     {
  177.         printf( "ERROR: creator set to bogus value!  It must be exactly four\n" );
  178.         printf( "       four characters.  Try again." );
  179.         fflush( stdout );
  180.         goto RedoDialog;
  181.     }
  182.     _fcreator = tempstr[1];
  183.     _fcreator <<= 8;
  184.     _fcreator |= tempstr[2] & 0xff;
  185.     _fcreator <<= 8;
  186.     _fcreator |= tempstr[3] & 0xff;
  187.     _fcreator <<= 8;
  188.     _fcreator |= tempstr[4] & 0xff;
  189.     
  190.     if ( itemHit == 2 )
  191.         listflag = 1;
  192.     else
  193.         listflag = 0;
  194.         
  195.     printf( "\n\n\n" );
  196.     
  197.     size = 0;
  198.     forceFlag = 0;
  199.     fseek( in, 0, SEEK_SET );
  200.     while ( 1 )
  201.     {
  202.         if ( fread( block, 512, 1, in ) != 1 )
  203.             break;
  204.         if ( fp->name[0] == '\0' )
  205.         {
  206.             break;
  207.         }
  208.         size = readnum( fp->size, 12 );
  209.         for ( i = 0; i < NAMESIZE; i++ )
  210.             if ( fp->name[i] == '\0' )
  211.                 break;
  212.         if ( forceFlag == 0 )
  213.         {
  214.             for ( j = 0; j < i; j++ )
  215.             {
  216.                 if ( fp->name[j] < ' ' || fp->name[j] > 127 )
  217.                 {
  218.                     printf( "\nERROR: bad character in file name.\n" );
  219.                     if ( StopAlert( 129, 0 ) == 2 )
  220.                     {
  221.                         forceFlag = 1;
  222.                         break;
  223.                     }
  224.                     else
  225.                         goto StartOver;
  226.                 }
  227.             }
  228.         }
  229.         if ( i && fp->name[i-1] == '/' && size == 0 )
  230.         {
  231.             printf( "DIRECTORY %s\n", fp->name );
  232.             if ( ! listflag )
  233.             {
  234.                 int err;
  235.                 uchar    mname[128];
  236.                 
  237.                 mname[0] = 1;
  238.                 mname[1] = ':';
  239.                 if ( fp->name[0] == '/' )
  240.                     i = 1;
  241.                 else
  242.                     i = 0;
  243.                 for ( ; fp->name[i] != '\0'; i++ )
  244.                 {
  245.                     if ( fp->name[i] == '/' )
  246.                         fp->name[i] = ':';
  247.                     mname[++mname[0]] = fp->name[i];
  248.                 }
  249.                 if ( mname[mname[0]] == ':' && mname[0] > 1 )
  250.                     mname[0]--;
  251.                 mname[1+mname[0]] = '\0';
  252.                 h.fileParam.ioCompletion = 0;
  253.                 h.fileParam.ioNamePtr = mname;
  254.                 h.fileParam.ioVRefNum = 0;
  255.                 h.fileParam.ioDirID = 0;
  256.                 err = PBDirCreate( &h, 0 );
  257.                 if ( err )
  258.                 {
  259.                     printf( "ERROR: creation of directory failed!\n" );
  260.                     goto StartOver;
  261.                 }
  262.             }
  263.             continue;
  264.         }
  265.         else if ( fp->link[0] && size == 0 )
  266.         {
  267.             printf( "WARNING: %s was linked to %s.  Ignored\n", fp->name, &fp->link[1] );
  268.             continue;
  269.         }
  270.         else
  271.             printf( "%s, %ld bytes\n", fp->name, size );
  272.         
  273.         if ( ! listflag )
  274.         {
  275.             FILE    * wp;
  276.             int        c;
  277.             int        pad;
  278.             char    mname[128];
  279.             
  280.             mname[0] = ':';
  281.             if ( fp->name[0] == '/' )
  282.                 i = 1;
  283.             else
  284.                 i = 0;
  285.             for ( c = 1; fp->name[i] != '\0'; i++ )
  286.             {
  287.                 if ( fp->name[i] == '/' )
  288.                     fp->name[i] = ':';
  289.                 mname[c++] = fp->name[i];
  290.             }
  291.             mname[c] ='\0';
  292.             
  293.             pad = (512 - (size % 512)) % 512;
  294.             wp = fopen( mname, "wb" );
  295.             if ( wp == NULL )
  296.             {
  297.                 printf( "ERROR: could not create!...skipping\n" );
  298.                 goto skipall;
  299.             } 
  300.             while ( size-- > 0 )
  301.             {
  302.                 c = getc(in);
  303.                 if ( c == 0x0A && convertFlag )
  304.                     c = 0x0D;
  305.                 putc(c,wp);
  306.             }
  307.  
  308.             while ( pad-- > 0 )
  309.                 getc(in);
  310.             fclose(wp);
  311.         }
  312.         else
  313.         {
  314.             if ( ! listflag )
  315.                 printf( "---unnamed file skipped\n" );
  316. skipall:            
  317.             size += 511; size /= 512;
  318.             
  319.             while ( size-- > 0 )
  320.             {
  321.                 if ( fread( block, 512, 1, in ) != 1 )
  322.                     break;
  323.             }
  324.             if ( size >= 0 )
  325.             {
  326.                 printf( "ERROR: read failed or unexpected end of file.\n" );
  327.                 break;
  328.             }
  329.         }
  330.     }
  331.     printf( "%s complete.\n", listflag ? "Listing" : "Extraction" );
  332.     fflush( stdout );
  333.     if ( listflag )
  334.         goto RedoDialog;
  335.     else
  336.         goto StartOver;
  337. }
  338.  
  339. void HiliteDefault( DialogPtr d )
  340. {
  341.     int ItemType;
  342.     Handle Item;
  343.     Rect ItemRect;
  344.     
  345.     GrafPtr savePort;
  346.     
  347.     GetPort( &savePort );
  348.     SetPort( d );
  349.     
  350.     GetDItem( d, 1, &ItemType, &Item, &ItemRect );
  351.     InsetRect( &ItemRect, -4, -4 );
  352.     PenSize( 3, 3 );
  353.     FrameRoundRect( &ItemRect, 16, 16 );
  354.     
  355.     SetPort( savePort );
  356. }
  357.  
  358.